package infra

import (
	"errors"
	"fmt"
	"os"
	"sync"

	"gitee.com/hgslb/base"
	"github.com/boltdb/bolt"
)

var (
	DOMAIN_TABLE       = "domain"
	ZONE_COUNTRY_TABLE = "zone.country"
	DOMAIN_IP_TABLE    = "domain.zone.ip"
)

type KvPair struct {
	Key   string
	Value []byte
}

type KvDb struct {
	mu  sync.Mutex
	bdb *bolt.DB
}

func (kdb *KvDb) StartDb() {
	os.MkdirAll(base.GslbConf.Infra.KvDns, 0755)
	dbName := fmt.Sprintf("%s/blot.db", base.GslbConf.Infra.KvDns)
	db, err := bolt.Open(dbName, 0600, nil)
	if err != nil {
		base.GslbLog.Infof("Open db:%s, failed:%s", dbName, err)
		panic(err)
	}
	kdb.bdb = db
}

func (kdb *KvDb) Close() {
	if kdb.bdb != nil {
		kdb.bdb.Close()
	}
}

func (kdb *KvDb) GetByKey(table string, key string) (*KvPair, error) {
	var value *KvPair
	err := kdb.bdb.View(func(tx *bolt.Tx) error {
		buck := tx.Bucket([]byte(table))
		if buck == nil {
			return errors.New("empty")
		}
		bKey := []byte(key)
		v := buck.Get(bKey)
		if v == nil {
			return errors.New("empty")
		}
		value = &KvPair{Key: key, Value: v}
		return nil
	})
	return value, err
}

func (kdb *KvDb) Update(table string, value *KvPair) error {
	err := kdb.bdb.Update(func(tx *bolt.Tx) error {
		buck, err := tx.CreateBucketIfNotExists([]byte(table))
		if err != nil {
			return err
		}
		bKey := []byte(value.Key)
		err = buck.Put(bKey, []byte(value.Value))
		if err != nil {
			return err
		}
		return nil
	})
	return err
}
